/**
* @author: zhazhjie
* @email: zhazhjie@vip.qq.com
* @date: 2018-06-12 17:52:54
* @version: 1.0
*/

<template>
  <transition name='fade'>
    <div
      class="popup-wrapper"
      :style="{zIndex}"
      v-show='showFlag'
      v-if="showFlag||initFlag">
      <div class="modal" @click='emitClose' @touchmove.stop.prevent></div>
      <div
        class="popup"
        :class='[position]'
        @touchstart="touchStart"
        @touchmove="onTouchMove"
        :style="popupStyle">
        <div class="popup-title">
          <div v-if="title" v-html="title"></div>
          <slot v-else name='title'>提示</slot>
        </div>
        <slot name='header'/>
        <slot name='out'/>
        <div class="popup-content" :class="isIOS?'scroll-box':''">
          <div v-if="content" v-html="content"></div>
          <slot v-else/>
        </div>
        <slot name="footer"/>
        <div class="operate" v-if='!simple&&position==="middle"'>
          <f-button type="plain" size='small' @click='handleClose'>取消</f-button>
          <f-button size='small' @click='handleSubmit' :loading="loading">确认</f-button>
        </div>
        <i class="close" v-else @click='handleClose'>×</i>
      </div>
    </div>
  </transition>
</template>

<script>
import fButton from '../button';
import {getDirection, getScroller} from '../util';
import {Validate} from 'js-utils/validate';

export default {
  name: 'f-popup',
  props: {
    showFlag: {
      type: Boolean,
      default: false
    },
    loading: {
      type: Boolean,
      default: false
    },
    position: {
      type: String,
      default: 'middle'
    },
    title: {
      type: String,
      default: ''
    },
    content: {
      type: String,
      default: ''
    },
    simple: {
      type: Boolean,
      default: false
    },
    zIndex: {
      type: [Number, String],
      default: 999
    },
    closeOnClickModal: {
      type: Boolean,
      default: true
    },
    maxHeight: {
      type: String,
      default: '90vh'
    },
    appendToBody: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isIOS: Validate.isIOS(),
      initFlag: false
    };
  },
  components: {fButton},
  watch: {
    showFlag(val) {
      this.setBodyScroll(val);
      if (val && !this.initFlag) {
        this.initFlag = true;
      }
    }
  },
  methods: {
    resetTouchStatus() {
      this.direction = '';
      this.deltaX = 0;
      this.deltaY = 0;
      this.offsetX = 0;
      this.offsetY = 0;
    },
    touchStart(event) {
      this.resetTouchStatus();
      this.startX = event.touches[0].clientX;
      this.startY = event.touches[0].clientY;
    },
    touchMove(event) {
      const touch = event.touches[0];
      // safari back will set clientX to negative number
      this.deltaX = touch.clientX < 0 ? 0 : touch.clientX - this.startX;
      this.deltaY = touch.clientY - this.startY;
      this.offsetX = Math.abs(this.deltaX);
      this.offsetY = Math.abs(this.deltaY);
      // lock direction when distance is greater than a certain value
      const LOCK_DIRECTION_DISTANCE = 10;
      if (
        !this.direction ||
        (this.offsetX < LOCK_DIRECTION_DISTANCE &&
          this.offsetY < LOCK_DIRECTION_DISTANCE)
      ) {
        this.direction = getDirection(this.offsetX, this.offsetY);
      }
    },
    onTouchMove(event) {
      this.touchMove(event);
      const direction = this.deltaY > 0 ? '10' : '01';
      const el = getScroller(event.target, this.$el);
      const {scrollHeight, offsetHeight, scrollTop} = el;
      let status = '11';

      /* istanbul ignore next */
      if (scrollTop === 0) {
        status = offsetHeight >= scrollHeight ? '00' : '01';
      } else if (scrollTop + offsetHeight >= scrollHeight) {
        status = '10';
      }

      /* istanbul ignore next */
      if (
        status !== '11' &&
        this.direction === 'vertical' &&
        !(parseInt(status, 2) & parseInt(direction, 2))
      ) {
        event.preventDefault();
        event.stopPropagation();
      }
    },
    emitClose(e) {
      if (this.closeOnClickModal) {
        this.handleClose();
      }
    },
    handleClose() {
      this.$emit('update:showFlag', false);
    },
    handleSubmit() {
      //this.handleClose();
      this.$emit('submit');
    },
    setBodyScroll(flag) {
      if (flag) {
        document.body.classList.add('overflow-hide');
      } else {
        document.body.classList.remove('overflow-hide');
      }
    },
    init() {
      if (this.appendToBody) {
        document.body.appendChild(this.$el);
      }
    },
    clear() {
      if (this.appendToBody) {
        document.body.removeChild(this.$el);
      }
    }
  },
  computed: {
    popupStyle() {
      let hasMaxHeight = this.position === 'middle' || this.position === 'bottom';
      return {
        maxHeight: hasMaxHeight ? this.maxHeight : null
      };
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    this.clear();
  }
};
</script>

<style lang="scss" scoped>
@import "../../style/popup";
</style>
